﻿using System;
using System.Collections;
using System.Text;
using Microsoft.Xna.Framework;

namespace SAM3D
{
    public interface ICamera : ITransformable
    {
        Matrix View { get; }
        Matrix Projection { get; }
        BoundingFrustum Frustrum { get; }
        event EventHandler Moved;
    }

    public class Camera : TransformableGameComponent, ICamera
    {
        public Camera(Game game, Transform transform) : base(game, transform)
        {
            _projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, game.GraphicsDevice.Viewport.Width/
                                                  (float)game.GraphicsDevice.Viewport.Height, .1f, 10000);
            _viewMatrix = Matrix.CreateLookAt(Transform.Position, Transform.TransformVector(Vector3.Forward), Vector3.Up);

            _bf = new BoundingFrustum(ViewProjectionMatrix);

            transform.Changed += RebuildView;
        }

        private Matrix _viewMatrix;

        private Matrix _projectionMatrix;

        public Matrix ViewProjectionMatrix { get { return _viewMatrix*_projectionMatrix; } }

        public Matrix View
        {
            get { return _viewMatrix; }
        }

        public Matrix Projection
        {
            get { return _projectionMatrix; }
        }

        private BoundingFrustum _bf;

        private void RebuildView(object sender, EventArgs args)
        {
            _viewMatrix = Matrix.CreateLookAt(Transform.Position, Transform.TransformVector(Vector3.Forward), Vector3.Up);
            _bf = new BoundingFrustum(_viewMatrix * _projectionMatrix);
            Moved.Invoke(this, EventArgs.Empty);
        }

        public BoundingFrustum Frustrum
        {
            get { return _bf; }
        }
        public event EventHandler Moved;
    }

    interface ICameraService
    {
        ICamera GetCamera();
    }
}
